<template>
  <div>
    <span style="padding-left: 10px; display: inline-block">货物名称
      <el-input v-model="goodsName"
                style="width: 200px"
                class="keyword"
                placeholder="请输入需搜索的货物名称" />
    </span>
    <el-table border
              :data="filteredRecords"
              class="table-wrap"
              style="width: 100%"
              highlight-current-row
              show-summary
              :summary-method="calcSummaries"
              v-bind="$attrs">
      <template v-for="(column, index) in columns">
        <el-table-column v-if="!column.hidden"
                         :key="index"
                         align="center"
                         :prop="column.name"
                         :label="column.label"
                         :column-key="column.name"
                         :width="column.width"
                         :show-overflow-tooltip="true">
          <template slot-scope="{ row }">
            <span v-if="editable({ column, row })">
              <el-input v-if="column.type === 'number'"
                        v-model.trim="row[column.name]"
                        maxlength="8"
                        :disabled="disabled({ column, row })"
                        @input="handleBlur({ column, row })" />
              <el-input v-else
                        v-model="row[column.name]"
                        maxlength="20"
                        :disabled="disabled({ column, row })" />
            </span>
            <span v-else>
              <span v-if="triggered({ column, row, index })">
                <GoodsSignTip v-if="showSignTip(row, column)"
                              :value="{ 
                                ...row.goodsSign, 
                                signQuantity: row.goodsSign.quantity || (row.goodsSign.quantity === 0 ? 0 : row.quantity), 
                                quantity: row.quantity,
                                receiptRejects: row.receiptRejects
                              }">
                  <template>
                    <GoodsPen v-model="row.editing"
                              :readonly="readonly"
                              :label="sum(row)"
                              :show-sign-tip="showSignTip(row, column)"
                              v-bind="$attrs"
                              @clear="handleClear({ column, row })"
                              @refuseSign="editRefuseSign({ row })" />
                  </template>
                </GoodsSignTip>
                <GoodsPen v-else
                          v-model="row.editing"
                          :label="sum(row)"
                          v-bind="$attrs"
                          @clear="handleClear({ column, row })"
                          @refuseSign="editRefuseSign({ row })" />
              </span>
              <span v-else>
                <GoodsSignTip v-if="showSignTip(row, column)"
                              :value="{ 
                                ...row.goodsSign, 
                                signQuantity: row.goodsSign.quantity || (row.goodsSign.quantity === 0 ? 0 : row.quantity), 
                                quantity: row.quantity,
                                receiptRejects: row.receiptRejects
                              }">
                  <template>
                    <GoodsPen v-model="row.editing"
                              :readonly="readonly"
                              :label="sum(row)"
                              :show-sign-tip="showSignTip(row, column)"
                              v-bind="$attrs"
                              @clear="handleClear({ column, row })"
                              @refuseSign="editRefuseSign({ row })" />
                  </template>
                </GoodsSignTip>
                <span v-else>{{ row[column.name] }}</span>
              </span>
            </span>
          </template>
        </el-table-column>
      </template>
    </el-table>
    <GoodsRefuseSign v-if="!!records[currentIndex]"
                     v-model="records[currentIndex].rejects"
                     :visible.sync="visible" />
    <!-- 分页 -->
    <div v-if="total > 0"
         class="page-box">
      <el-pagination background
                     :page-sizes="[10, 20, 30, 50]"
                     :page-size.sync="size"
                     :current-page.sync="page"
                     layout="total, sizes, prev, pager, next, jumper"
                     :total="total"
                     @size-change="handleSizeChange"
                     @current-change="handlePageChange">
      </el-pagination>
    </div>
  </div>
</template>
<script>
import _ from "lodash";
import GoodsPen from "@/components/basic/GoodsPen.vue";
import GoodsSignTip from "@/components/basic/GoodsSignTip.vue";
import GoodsRefuseSign from "@/components/basic/GoodsRefuseSign.vue";
const SCHEMA = [
  {
    label: "货物名称",
    name: "goodsName",
    readonly: true,
    align: "center"
  },
  {
    label: "物料编码",
    name: "barcode",
    width: "100px",
    readonly: true
  },
  {
    label: "规格",
    name: "spec",
    width: "100px",
    readonly: true
  },
  {
    label: "重量(公斤)",
    name: "weight",
    width: "100px",
    readonly: true
  },
  {
    label: "体积(方)",
    name: "volume",
    readonly: true
  },
  {
    label: "数量",
    name: "quantity",
    readonly: true
  },
  {
    label: "实签数量",
    name: "signQuantity",
    type: "number"
  },
  {
    label: "异常数量",
    name: "exceptionQuantity",
    trigger: true
  },
  {
    label: "缺少",
    name: "lackQuantity",
    type: "number"
  },
  {
    label: "丢失",
    name: "loseQuantity",
    type: "number"
  },
  {
    label: "破损",
    name: "damageQuantity",
    type: "number"
  },
  {
    label: "其他",
    name: "otherQuantity",
    type: "number"
  },
  {
    label: "异常描述",
    name: "exceptionDesc"
  },
  {
    label: "批次",
    name: "batchNo",
    readonly: true
  },
  {
    label: "备注",
    name: "desc",
    readonly: true
  }
];

const TOTAL_COLUMNS = ["weight", "volume", "quantity"];
const EXCLUDE_SUMMARY_COLUMNS = ["desc", "batchNo", "exceptionDesc"];

export default {
  name: "GoodsList",
  components: { GoodsPen, GoodsSignTip, GoodsRefuseSign },
  props: {
    columns: {
      type: Array,
      default () {
        return SCHEMA;
      }
    },
    value: Array,
    addition: {
      type: Object,
      default () {
        return {
          goodsName: "补差",
          weight: 0,
          volume: 0
        };
      }
    },
    totalData: {
      type: Object,
      default () {
        return {
          goodsName: "合计",
          weight: 0,
          volume: 0,
          quantity: 0
        };
      }
    },
    readonly: Boolean
  },
  data () {
    return {
      size: 10,
      page: 1,
      goodsName: "",
      visible: false,
      records: [],
      currentIndex: 0
    };
  },
  computed: {
    sum () {
      return (goods) => {
        const {
          lackQuantity = 0,
          loseQuantity = 0,
          damageQuantity = 0,
          otherQuantity = 0
        } = goods;
        return (
          Number(lackQuantity) +
          Number(loseQuantity) +
          Number(damageQuantity) +
          Number(otherQuantity) || 0
        );
      };
    },
    totalValue () {
      return ({ property: name }, row, index) => {
        // if (name !== "weight" && name != "volume") {
        //   return row[name];
        // }
        // if (index === this.filteredRecords.length - 1) {
        //   return row[name];
        // }
        // return row[name] * row.quantity;
        if (['signQuantity', 'exceptionQuantity'].includes(name))
          return row[name];
      };
    },
    editable () {
      return ({ column, row }) => {
        return (
          !this.readonly && !column.readonly && !column.trigger && row.editing
        );
      };
    },
    disabled () {
      return ({ column, row }) => {
        return !this.sum(row) && column.name === "exceptionDesc";
      };
    },
    triggered () {
      return ({ column, row, index }) => {
        return (
          column.trigger &&
          !this.readonly &&
          // index !== this.filteredRecords.length - 1 &&
          row.goodsName !== "补差"
        );
      };
    },
    start () {
      return this.page <= 1 ? 0 : (this.page - 1) * this.size;
    },
    end () {
      return this.page * this.size;
    },
    total () {
      const filteredRecords = this.records.filter((record) =>
        this.containsName(record)
      );
      return filteredRecords.length;
    },
    containsName () {
      return (record) =>
        !this.goodsName ||
        record.goodsName.toLowerCase().includes(this.goodsName.toLowerCase());
    },
    filteredRecords () {
      const filteredRecords = this.records
        .filter((record) => this.containsName(record))
        .filter((record, index) => {
          return index < this.end && index >= this.start;
        });

      filteredRecords.push(this.addition);
      return filteredRecords;
    },
    outputRecords () {
      this.records.forEach((goods) => {
        goods.exceptionQuantity = this.sum(goods);
        goods.goodsSign.isSignTip = goods.exceptionQuantity > 0;
      });
      return this.records;
    },
    showSignTip () {
      return ({ goodsSign }, { name }) =>
        name === "exceptionQuantity"
        && goodsSign?.quantity != null
        && goodsSign?.quantity != undefined
        && goodsSign.isSignTip;
    }
  },
  created () {
    this.records = _.cloneDeep(this.value || []);
  },
  methods: {
    calcSummaries ({ columns }) {
      const summaries = [];
      const rows = [...this.records, this.addition]
        .filter((record) => this.containsName(record))
      columns.forEach((column, index) => {
        if (index === 0) {
          summaries[index] = "合计";
          return;
        }
        if (TOTAL_COLUMNS.includes(column.property)) {
          summaries[index] = this.totalData[column.property];
          return
        }

        if (EXCLUDE_SUMMARY_COLUMNS.includes(column.property)) {
          summaries[index] = "";
          return;
        }

        let values = [];
        if ("exceptionQuantity" === column.property) {
          values = rows.map((row) => Number(this.sum(row)));
        } else {
          values = rows.map((row, index) =>
            Number(this.totalValue(column, row, index))
          );
        }

        if (values.every((value) => !value)) {
          summaries[index] = "";
          return;
        }

        summaries[index] = values
          .filter((value) => !!value)
          .reduce((a, b) => a + b, 0);

        if (summaries[index] && String(summaries[index]).indexOf('.') > 0) {
          summaries[index] = Number(summaries[index]).toFixed(2)
        }
      });

      return summaries;
    },
    handleBlur ({ row, column }) {
      const { name, type } = column;
      if (type === "number") {
        let regStr = /^[0-9]\d*$/;
        if (name && !regStr.test(row[name])) {
          row[name] = null;
        } else {
          row[name] = Number(row[name]);
        }
      }
    },
    handleSizeChange () { },
    handlePageChange () { },
    handleClear ({ row }) {
      if (this.readonly) {
        return;
      }
      row.editing = false;

      console.log("======><", row.sign, row.goodsSign)
      const resetSignQuantity = row?.goodsSign?.signQuantity || (row?.goodsSign?.signQuantity === 0 ? 0 : row.quantity);
      const resetLackQuantity = row?.goodsSign?.lackQuantity;
      const resetLoseQuantity = row?.goodsSign?.loseQuantity;
      const resetDamageQuantity = row?.goodsSign?.damageQuantity;
      const resetOtherQuantity = row?.goodsSign?.otherQuantity;
      const resetExceptionDesc = row?.goodsSign?.exceptionDesc;
      this.$set(row, "lackQuantity", resetLackQuantity);
      this.$set(row, "loseQuantity", resetLoseQuantity);
      this.$set(row, "damageQuantity", resetDamageQuantity);
      this.$set(row, "otherQuantity", resetOtherQuantity);
      this.$set(row, "exceptionDesc", resetExceptionDesc);
      this.$set(row, "signQuantity", resetSignQuantity);
      this.$set(row, "rejects", row?.goodsSign?.rejects || []);
    },
    editRefuseSign ({ row }) {
      const indexs = this.records.findIndex(({ batchNo, goodsId }) =>
        batchNo === row?.batchNo && goodsId === row?.goodsId)
      this.currentIndex = indexs
      this.visible = true
    },
    debounceInput: _.debounce(function (value) {
      this.$emit("input", value);
    }, 200)
  },
  watch: {
    value (value) {
      this.records = _.cloneDeep(value || []);
    },
    outputRecords: {
      handler (value) {
        this.debounceInput(value);
      },
      deep: true
    }
  }
};
</script>
<style lang="scss" scoped>
.required {
  /deep/ input {
    border: 1px solid var(--prev-color-text-purered);
  }
}

.keyword {
  margin-bottom: 18px;
}

::v-deep .el-table {
  font-size: 14px;
}

::v-deep .el-table .cell {
  line-height: 30px;
}

::v-deep .el-table .el-input__inner {
  height: 32px !important;
}

.page-box {
  text-align: center;
  margin-top: 10px;
  margin-bottom: 10px;
}
</style>
